import type { FormItemProps } from "element-plus";
import type { Component, VNode } from "vue";
import { markRaw } from "vue";
import type { ExtractProps } from "../types";
import { ElOption, ElRadio, ElCheckbox } from "element-plus";

/**
 * 创建一个组件元素配置对象
 * @param type Vue3 组件
 * @param props 组件属性配置
 * @returns 包含 type 和 props 的对象
 */
export const itemType = <P extends Component>(
  type: P,
  props?: ExtractProps<P> | ((data: any) => ExtractProps<P>)
) => ({ type: markRaw(type), props: props });

export const optionComMap = {
  ElSelect: ElOption,
  ElRadioGroup: ElRadio,
  ElCheckboxGroup: ElCheckbox,
} as Record<string, Component>;

/** 表单项目选项类型 */
export type FormItemOptionType = {
  label: string;
  value: string | number;
  disabled?: boolean;
};

/** 表单项目选项 */
export type FormItemOptions<T = any> =
  | FormItemOptionType[]
  | ((data: T) => FormItemOptionType[])
  | ((data: T) => {
      /** 获取选项的异步函数,如果数据获取失败请返回 resolve([]) */
      getOptions: (data: T) => Promise<FormItemOptionType[]>;
      /** 用于缓存不同条件的数据 */
      key: string;
    });

/** 表单项目配置 */
export type FormItemConfig = {
  props: Record<string, any>;
  visible: boolean;
  options?: FormItemOptionType[];
};

/** 表单项目配置 */
export interface FormItem<D = any>
  extends Partial<Omit<FormItemProps, "prop">> {
  /** 表单项的类型，决定了渲染的组件 */
  type: Component | VNode;
  /** 表单项的属性配置 */
  props?: Record<string, any> | ((data: D) => Record<string, any>);
  /** 表单项的 key 值，用于标识表单项,绑定数据 */
  key: keyof D & string;
  /** 当前项模是否显示 */
  show?: (data: D) => boolean;
  /** 表单项占据的栅格列数 1 - 24 */
  span?: number;
  /** 组件插槽 */
  slot?: Record<string, unknown>;
  /** 表单项的选项 */
  options?: FormItemOptions<D>;
}
